package com.fin.quant.app.asset.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.fin.quant.app.asset.service.RankingService;
import com.fin.quant.app.vo.*;
import com.fin.quant.domain.entity.AssetEntity;
import com.fin.quant.domain.service.AssetDaoService;
import com.fin.quant.domain.service.RankingDaoService;
import com.fin.quant.instra.mysql.model.Asset;
import com.fin.quant.instra.mysql.model.RankingAsset;
import com.fin.quant.instra.mysql.model.RankingType;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 排行榜应用服务实现
 */
@Service
public class RankingServiceImpl implements RankingService {

    @Autowired
    private RankingDaoService rankingDaoService;

    @Autowired
    private AssetDaoService assetDaoService;

    @Override
    public RankingTypeWrapperVO getEnabledRankingTypes() {
        List<RankingType> enabledRankingTypes = rankingDaoService.getEnabledRankingTypes();

        List<RankingTypeVO> rankingTypeVOList = enabledRankingTypes.stream().map(rankingType -> {
            return convertRankingTypeVO(rankingType);
        }).collect(Collectors.toList());

        RankingTypeWrapperVO wrapperVO = new RankingTypeWrapperVO();
        wrapperVO.setTypes(rankingTypeVOList);
        return wrapperVO;
    }

    private static RankingTypeVO convertRankingTypeVO(RankingType rankingType) {
        RankingTypeVO vo = new RankingTypeVO();
        vo.setTypeId(rankingType.getTypeId());
        vo.setName(rankingType.getName());
        vo.setTitle(rankingType.getTitle());
        vo.setDescription(rankingType.getDescription());
        vo.setIcon(rankingType.getIcon());
        vo.setSortOrder(rankingType.getSortOrder());
        vo.setEnabled(rankingType.getEnabled() == 1);
        vo.setMaxItems(rankingType.getMaxItems());

        String metricsConfig = rankingType.getMetricsConfig();
        MetricsConfigVO metricsConfigVO = JSON.parseObject(metricsConfig, MetricsConfigVO.class);
        vo.setMetricsConfig(metricsConfigVO);
        return vo;
    }

    private RankingTypeVO getRankingTypeById(String typeId) {
        RankingType rankingType = rankingDaoService.getRankingTypeById(typeId);
        RankingTypeVO rankingTypeVO = convertRankingTypeVO(rankingType);
        return rankingTypeVO;
    }

    @Override
    public RankingWrapperVO getRankingById(String typeId, int limit) {
        List<RankingAsset> rankingAssets = rankingDaoService.getRankingAssets(typeId, 10);

        List<RankingItemVO> items = rankingAssets.stream().map(rankingAsset -> {
            RankingItemVO itemVO = new RankingItemVO();
            itemVO.setId(rankingAsset.getId());
            itemVO.setRank(rankingAsset.getRankPosition());
            Long assetId = rankingAsset.getAssetId();
            AssetEntity asset = assetDaoService.findById(assetId);
            if (asset != null) {
                itemVO.setAsset(AssetVO.convertAssetToVO(asset));
            }
            String metrics = rankingAsset.getMetrics();
            Map metricsMap = JSON.parseObject(metrics, Map.class);
            itemVO.setMetrics(metricsMap);
            List<String> tags = JSON.parseArray(rankingAsset.getTags(), String.class);
            itemVO.setTags(tags);
            itemVO.setRiskLevel(rankingAsset.getRiskLevel());
            itemVO.setLastUpdated(DateUtil.format(rankingAsset.getLastUpdated(), "yyyy-MM-dd HH:mm:ss"));


            return itemVO;
        }).collect(Collectors.toList());

        RankingWrapperVO wrapperVO = new RankingWrapperVO();
        wrapperVO.setType(getRankingTypeById(typeId));
        wrapperVO.setItems(items);
        return wrapperVO;
    }

    @Override
    public BatchRankingWrapperVO getBatchRankings(List<String> typeIds, int limit) {


        Map<String, RankingWrapperVO> rankingsMap = Maps.newHashMap();

        for (String typeId : typeIds) {
            RankingWrapperVO rankingWrapperVO = getRankingById(typeId, limit);
            rankingsMap.put(typeId, rankingWrapperVO);
        }


        BatchRankingWrapperVO wrapperVO = new BatchRankingWrapperVO();
        wrapperVO.setRankings(rankingsMap);

        return wrapperVO;
    }
}
